package broadcast;

import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import sql.DBManager;
import sql.SqlHelper;

/**
 * 创建时间：2018年03月12日17:26 <br>
 * 作者：fuchaoyang <br>
 * 描述：ContentProvider内部其实最终还是操作数据库，只不过Android不同app是隔离的，无法直接访问别的app的数据库或者文件等，所以通过ContentProvider来暴露接口，供别的app操作数据库或文件
 * 1. onCreate() 默认执行在主线程，别做耗时操作，query() 也最好异步执行
 * 2. 上面的 4 个增删改查操作都可能会被多个线程并发访问，因此需要注意线程安全
 *
 * ContentProvider 使用 URI 标识要操作的数据. 要包括两部分：
 * authority：整个提供程序的符号名称
 * path：指向表的名称/路径
 *
 * content://authority/path
 */

public class MyContentProvider extends android.content.ContentProvider {

  public static final String AUTHORITY = "org.jaaksi.commondemo.broadcast.MyContentProvider";
  public static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
  public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/person");
  public static final String TABLE = SqlHelper.TABLE_PERSON;

  private static final int TABLE_CODE_PERSON = 2;
  private SQLiteDatabase mDatabase;

  static {
    //关联不同的 URI 和 code，便于后续 getType
    MATCHER.addURI(AUTHORITY, "person", TABLE_CODE_PERSON);
  }

  @Override public boolean onCreate() {
    mDatabase = DBManager.getInstance(getContext()).getWritableDatabase();
    return false;
  }

  @Nullable @Override
  public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
    @Nullable String[] selectionArgs, @Nullable String sortOrder) {
    return mDatabase.query(getTableName(uri), projection, selection, selectionArgs, null, null,
      sortOrder);
  }

  @Nullable @Override public String getType(@NonNull Uri uri) {
    return null;
  }

  @Nullable @Override public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
    mDatabase.insert(getTableName(uri), null, values);
    return null;
  }

  @Override public int delete(@NonNull Uri uri, @Nullable String selection,
    @Nullable String[] selectionArgs) {
    int deleteCount = mDatabase.delete(getTableName(uri), selection, selectionArgs);
    if (deleteCount > 0) {
      // 我们在ContentProvider的insert,update,delete等改变之后调用getContext().getContentResolver().notifyChange(uri, null);
      // 这样就通知那些监测databases变化的 ContentObserver 了
      // 我们可以通过 getContentResolver().registerContentObserver注册 ContentObserver
      getContext().getContentResolver().notifyChange(uri, null);
    }
    return deleteCount;
  }

  @Override
  public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
    @Nullable String[] selectionArgs) {
    int updateCount = mDatabase.update(getTableName(uri), values, selection, selectionArgs);
    if (updateCount > 0) {
      getContext().getContentResolver().notifyChange(uri, null);
    }
    return updateCount;
  }

  /**
   * 根据 Uri 通过matcher 获取对应的表名
   */
  private String getTableName(final Uri uri) {
    String tableName = "";
    int match = MATCHER.match(uri);
    switch (match) {
      case TABLE_CODE_PERSON:
        tableName = TABLE;
    }
    return tableName;
  }
}
